﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Semantics.Base;
namespace Semantics.Example.ParserExample
{
    public partial class SemanticNodeResolveForm : Form
    {
        LangNode LangNode;
        public SemanticNodeResolveForm(LangNode langnode)
        {
            InitializeComponent();
            this.LangNode = langnode;
            SetFormat();
        }

        public SemanticNode SelectedSemanticNode;
        void SetFormat()
        {
            System.Reflection.PropertyInfo[] properties = this.semanticNodeControlCandidates.GetType().GetProperties();
            for (int i = 0; i < properties.Length; i++)
            {
                if (properties[i].Name == "Format")
                {
                    properties[i].SetValue(this.semanticNodeControlCandidates, "%S:%V(%H)", null);
                    break;
                }
            }
        }
        Semantics.Parse.SemanticNodesAmbiguitiesResolve SemanticNodesAmbiguitiesResolve;
        private void SemanticNodeResolveForm_Load(object sender, EventArgs e)
        {
            if (this.LangNode.SemanticNodes.Count == 0)
            {
                MessageBox.Show(this, "LangNode has no SemanticNodes!");
                return;
            }
            TreeNode root = this.languageNodeControl1.ShowSemanticNode(this.LangNode.SemanticNodes[0], this.languageNodeControl1.Nodes, 0);
            this.languageNodeControl1.ExpandAll();
            IndexLangNode(root);
            SemanticNodesAmbiguitiesResolve = new Parse.SemanticNodesAmbiguitiesResolve(this.LangNode);
            SemanticNodesAmbiguitiesResolve.Reset();
            this.Next();
        }

        /// <summary>
        /// Key: LangNode.SN
        /// Value: TreeNode in languageNodeControl1
        /// </summary>
        SortedList<int, TreeNode> LangNodeIndex=new SortedList<int,TreeNode>();
        void IndexLangNode(TreeNode treenode)
        {
            SemanticNode semanticnode = (SemanticNode)treenode.Tag;
            LangNodeIndex.Add(semanticnode.LanguageNode.SN, treenode);
            foreach (TreeNode child in treenode.Nodes)
                IndexLangNode(child);
        }
        TreeNode CurrentTreeNode;
        bool Next()
        {
            List<SemanticNode> candidates = null;
            this.semanticNodeControlCandidates.Nodes.Clear();
            while (true)
            {

                if (!SemanticNodesAmbiguitiesResolve.MoveNext())
                {
                    return false;
                }
                candidates = this.SemanticNodesAmbiguitiesResolve.GetCandidatesSemanticNodes();
                if (candidates.Count > 1)
                {
                    ShowCandidatesSemanticNodes(candidates);
                    if (this.CurrentTreeNode != null)
                        this.CurrentTreeNode.ImageIndex = -1;
                    if (this.LangNodeIndex.ContainsKey(this.SemanticNodesAmbiguitiesResolve.CurrentLangNode.SN))
                    {
                        this.CurrentTreeNode = this.LangNodeIndex[this.SemanticNodesAmbiguitiesResolve.CurrentLangNode.SN];
                        this.CurrentTreeNode.ImageIndex = 0;
                        this.CurrentTreeNode.SelectedImageIndex = 0;
                    }
                    return true;
                }
                //else if (candidates.Count == 1)
                //{
                //    LangNode langnode = candidates[0].LanguageNode;
                //    if (langnode.AbsolutePos == 0 && langnode.Value.Length == langnode.Position.Pyramid.Dimension)
                //    {
                //        return ;
                //    }
                //}
            }
        }

        void Finish()
        {
            List<SemanticNode> semanticnodes =
                SemanticNodesAmbiguitiesResolve.GetRemainSemanticNodeOfLangNode(
                SemanticNodesAmbiguitiesResolve.CurrentLangNode);
            if (semanticnodes.Count != 1)
                throw new Exception("Wrong!");
            this.SelectedSemanticNode = semanticnodes[0];
            this.semanticNodeControlCandidates.Nodes.Clear();
            this.semanticNodeControlCandidates.ShowSemanticNode(
                this.SelectedSemanticNode, this.semanticNodeControlCandidates.Nodes, 0);
            this.Text = "Finished!";
            this.toolStripButtonFinish.Enabled = true;
        }

        void ShowCandidatesSemanticNodes(List<SemanticNode> candidates)
        {
            this.semanticNodeControlCandidates.Nodes.Clear();
            for (int i = candidates.Count - 1; i >= 0; i--)
            {
                this.semanticNodeControlCandidates.ShowSemanticNode(candidates[i], this.semanticNodeControlCandidates.Nodes, 0);
            }
        }

        private void semanticNodeControlCandidates_AfterSelect(object sender, TreeViewEventArgs e)
        {
        }

        private void semanticNodeControlCandidates_NodeSelectedEvent(SemanticNodeControl sender, SemanticNodeControl.NodeSelectedEventArgs e)
        {
            try
            {
                List<Edge> children = e.SelectedNode.Sense.Parent.Children;
                string text = null;
                bool senseincluded=false;
                for (int i = 0; i < children.Count && i < 5; i++)
                {
                    Node child=children[i].Outgoing;
                    text += child.Value+";";
                    if (child == e.SelectedNode.Sense)
                        senseincluded = true;
                }
                if (!senseincluded)
                    text += e.SelectedNode.Sense;
                this.toolStripStatusLabel1.Text = text;
            }
            catch (Exception exp)
            {
                MessageBox.Show(this, exp.ToString());
            }
        }

        private void semanticNodeControlCandidates_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                SemanticNode selectedsemanticnode = (SemanticNode)this.semanticNodeControlCandidates.SelectedNode.Tag;
                this.SemanticNodesAmbiguitiesResolve.Apply(selectedsemanticnode);
                if(!this.Next())
                    Finish();
            }
            catch (Exception exp)
            {
                MessageBox.Show(this, exp.ToString());
            }
        }

        private void toolStripButtonFinish_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }
    }
}
